package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/worklz/go-redis-lock"
	"github.com/go-redis/redis/v8"
)

func main() {
	// 初始化Redis客户端
	redisClient := redis.NewClient(&redis.Options{
		Addr:     "192.168.88.201:6379",
		Password: "123456", // 没有密码
		DB:       1,        // 默认DB
	})

	// 检查Redis连接
	ctx := context.Background()
	_, err := redisClient.Ping(ctx).Result()
	if err != nil {
		panic(fmt.Sprintf("Failed to connect to Redis: %v", err))
	}
	log.Println("Connected to Redis successfully")

	// redis锁初始化
	err = redislock.Init(
		func(ctx context.Context, args ...interface{}) (interface{}, error) {
			return redisClient.Do(ctx, args...).Result()
		},
		redislock.WithLogger(&MyLogger{}),
		redislock.WithFullKey(func(key string) string {
			return "redis.lock.example:" + key
		}),
	)
	if err != nil {
		panic(fmt.Sprintf("Failed to initialize redislock: %v", err))
	}

	// 示例1：基本使用方式（推荐使用Acquire+defer）
	fmt.Println("=== Example 1: Basic usage ===")
	lock1 := redislock.NewLock(
		"user:123",
		5*time.Second,
		redislock.WithWaitTime(10*time.Second),
		redislock.WithMaxHoldTime(30*time.Second),
	)
	release1, err := lock1.Acquire()
	if err != nil {
		log.Printf("Failed to acquire lock1: %v", err)
	} else {
		defer release1() // 确保释放
		log.Println("Lock1 acquired successfully")
		// 执行业务逻辑
		time.Sleep(2 * time.Second)
		log.Println("Lock1 business logic completed")
	}

	// 示例2：使用上下文自动释放
	fmt.Println("\n=== Example 2: Context auto release ===")
	ctx2, cancel2 := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel2()
	lock2 := redislock.NewLock(
		"order:456",
		5*time.Second,
		redislock.WithWaitTime(10*time.Second),
		redislock.WithContext(ctx2), // 绑定上下文
	)
	acquired2, err := lock2.Get()
	if err != nil {
		log.Printf("Failed to acquire lock2: %v", err)
	} else if acquired2 {
		log.Println("Lock2 acquired successfully")
		// 模拟忘记调用Release()
		log.Println("Lock2 will be auto released when context timeout")
		time.Sleep(5 * time.Second) // 超过上下文超时时间
		log.Println("Lock2 business logic completed (should be auto released)")
	}

	// 示例3：非等待模式
	fmt.Println("\n=== Example 3: Non-wait mode ===")
	lock3 := redislock.NewLock(
		"product:789",
		5*time.Second,
	)
	acquired3, err := lock3.Get()
	if err != nil {
		log.Printf("Failed to acquire lock3: %v", err)
	} else if acquired3 {
		defer lock3.Release()
		log.Println("Lock3 acquired successfully")
		time.Sleep(2 * time.Second)
		log.Println("Lock3 business logic completed")
	} else {
		log.Println("Lock3 is already held by others")
	}

	// 示例4：测试Finalizer兜底（模拟忘记释放）
	fmt.Println("\n=== Example 4: Finalizer test ===")
	go func() {
		lock4 := redislock.NewLock(
			"test:finalizer",
			10*time.Second,
			redislock.WithWaitTime(15*time.Second),
			redislock.WithMaxHoldTime(30*time.Second),
		)
		acquired4, err := lock4.Get()
		if err != nil {
			log.Printf("Failed to acquire lock4: %v", err)
			return
		}
		if acquired4 {
			log.Println("Lock4 acquired successfully (will forget to release)")
			// 模拟忘记调用Release()
			time.Sleep(5 * time.Second)
			log.Println("Lock4 goroutine exiting (forgot to release)")
			// 锁对象会在函数退出后成为垃圾，触发Finalizer
		}
	}()

	// 等待Finalizer执行
	time.Sleep(15 * time.Second)
	fmt.Println("\n=== All examples completed ===")

	// 优雅退出
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh
	log.Println("Shutting down...")
}
